using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Launcher
{
    public static class AssemblyLoaderParametersValidator
    {
        private static readonly char[] InvalidTypeNameChars = { ' ', '\t', '\n', '\r', '/', '\\', ':', '*', '?', '"', '<', '>', '|' };

        public static string ValidateAssemblyDirectory(string path)
        {
            if (string.IsNullOrWhiteSpace(path))
                return Path.GetFullPath(AppContext.BaseDirectory);

            try
            {
                var fullPath = Path.GetFullPath(path);
                return Directory.Exists(fullPath)
                    ? fullPath
                    : throw new DirectoryNotFoundException($"指定的程序集目录不存在: {fullPath}");
            }
            catch (Exception ex) when (ex is ArgumentException || ex is PathTooLongException || ex is NotSupportedException)
            {
                throw new ArgumentException($"无效的程序集目录: {path}", nameof(path), ex);
            }
        }

        public static string ValidateEntryAssemblyFile(string assemblyFile, string assemblyDirectory)
        {
            if (string.IsNullOrWhiteSpace(assemblyFile))
                throw new ArgumentException("入口程序集文件不能为空", nameof(assemblyFile));

            if (assemblyFile.IndexOfAny(Path.GetInvalidFileNameChars()) >= 0)
                throw new ArgumentException($"入口程序集文件名包含无效字符: {assemblyFile}", nameof(assemblyFile));

            if (!Path.HasExtension(assemblyFile))
                throw new ArgumentException("入口程序集文件必须包含扩展名（如 .dll）", nameof(assemblyFile));

            var fullPath = Path.Combine(assemblyDirectory, assemblyFile);
            return File.Exists(fullPath)
                ? fullPath
                : throw new FileNotFoundException($"入口程序集文件不存在: {fullPath}");
        }

        public static void ValidateEntryType(string typeName)
        {
            if (string.IsNullOrWhiteSpace(typeName))
                throw new ArgumentException("入口类型不能为空", nameof(typeName));

            if (!typeName.Contains('.') || typeName.EndsWith(".") || typeName.StartsWith("."))
                throw new ArgumentException("入口类型必须是完整的类型名称（包含命名空间）", nameof(typeName));

            if (typeName.IndexOfAny(InvalidTypeNameChars) >= 0)
                throw new ArgumentException($"入口类型包含无效字符: {typeName}", nameof(typeName));
        }

        public static void ValidateAssemblyLoadContextName(string contextName)
        {
            if (string.IsNullOrWhiteSpace(contextName))
                throw new ArgumentException("AssemblyLoadContext 名称不能为空", nameof(contextName));

            if (contextName.Length > 100)
                throw new ArgumentException("AssemblyLoadContext 名称长度不能超过100个字符", nameof(contextName));
        }

        public static string ValidateThreadApartmentState(string state)
        {
            if (string.IsNullOrWhiteSpace(state))
                throw new ArgumentException("线程单元状态不能为空", nameof(state));

            var upperValue = state.ToUpperInvariant();
            return upperValue switch
            {
                "STA" or "MTA" or "UNKNOWN" => upperValue,
                _ => throw new ArgumentException("线程单元状态必须是 STA、MTA 或 UNKNOWN", nameof(state))
            };
        }
    }
}